﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading;
using System.Web;
using System.Web.Security;
using BlogManager.Core.Model;

namespace BlogManager.Core.Security
{
    public class AuthenticationService
    {
        public void RegisterUser(Data.Entities.User user)
        {
            CreateCustomPrincipal(user);
            CreateAuthenticationCookie(user);
        }

        public void DeregisterUser(Data.Entities.User user)
        {
            Thread.CurrentPrincipal = null;
        }

        public UserInformation GetCurrentUser()
        {
            //Get the user from the principal...
            var userId = Convert.ToInt32(Thread.CurrentPrincipal.Identity);

            var user = Data.Entities.User.SingleOrDefault(x => x.Id == userId);
            if (user != null)
            {
                var roles = GetUserRoles(user);
                var userInfo = new UserInformation {Id=user.Id, UserName = user.UserName, Email = user.Email, Roles = roles};
            }

            return null;
        }

        protected void CreateCustomPrincipal(Data.Entities.User user)
        {
            var roles = GetUserRoles(user);

            var identity = new GenericIdentity(user.Id.ToString());
            var principal = new GenericPrincipal(identity, roles);

            HttpContext.Current.User = principal;
            Thread.CurrentPrincipal = principal;
        }

        protected string[] GetUserRoles(Data.Entities.User user)
        {
            return (from r in Data.Entities.Role.All()
                    join ru in Data.Entities.User_Role.All() on r.Id equals ru.RoleId
                    join u in Data.Entities.User.All() on ru.UserId equals u.Id
                    where u.Id == user.Id
                    select r.Name).ToArray();
        }

        protected void CreateAuthenticationCookie(Data.Entities.User user)
        {
            //For aditional Data...
            string userData = "";

            // Create the authentication ticket
            var authTicket =
                new FormsAuthenticationTicket(
                    1, // version
                    user.UserName,
                    DateTime.Now,
                    DateTime.Now.AddMinutes(120), false, userData);

            // Encrypt the ticket
            string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

            // Create a cookie and add the cookie to the response
            var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
            HttpContext.Current.Response.Cookies.Add(authCookie);
        }
    }
}